package com.example.selfservicestation.fragment

import android.annotation.SuppressLint
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.GridLayoutManager
import com.example.selfservicestation.R
import com.example.selfservicestation.adapter.LockStateAdapter
import com.example.selfservicestation.base.BaseBindingFragment
import com.example.selfservicestation.bean.LockStateBean
import com.example.selfservicestation.constant.DEFAULT_LOCK_COUNT
import com.example.selfservicestation.constant.SP_LOCK_COUNT
import com.example.selfservicestation.databinding.FragmentTestLockBinding
import com.example.selfservicestation.enums.LockStateEnum
import com.example.selfservicestation.extensions.safeNavigate
import com.example.selfservicestation.mob.MBFrame
import com.example.selfservicestation.mob.MODBUS_MIN_SEND_INTERVAL
import com.example.selfservicestation.mob.ModBusController
import com.example.selfservicestation.singleton.SharedPreferenceUtil
import com.example.selfservicestation.util.getBitValueFrom8Bits
import com.example.selfservicestation.util.toHexString
import com.example.selfservicestation.widget.GridItemDecoration
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.asFlow
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch

class TestLockFragment: BaseBindingFragment<FragmentTestLockBinding>(FragmentTestLockBinding::inflate) {

    private lateinit var lockStateAdapter: LockStateAdapter
    private val lockDataList = mutableListOf<LockStateBean>()
    private var lockCount = DEFAULT_LOCK_COUNT

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        initViews()
        checkLockState()
    }

    @SuppressLint("SetTextI18n")
    private fun initViews(){
        showLoading()
        lockCount = SharedPreferenceUtil.getInt(SP_LOCK_COUNT, DEFAULT_LOCK_COUNT)
        binding.tvLockCount.text = "仓位：${lockCount}    正常：${lockCount}    未响应：0"
        for (item in 1.. lockCount){
            lockDataList.add(LockStateBean(item,LockStateEnum.LOCK))
        }
        lockStateAdapter = LockStateAdapter(lockDataList){ lockStateBean ->
            openLock(lockStateBean)
        }
        binding.rvLock.apply {
            adapter = lockStateAdapter
            layoutManager = GridLayoutManager(context,6)
            if (itemDecorationCount == 0){
                addItemDecoration(GridItemDecoration(6,16,16))
            }
        }

        binding.btnLockTest.setOnClickListener {
            openLocksInOrder()
        }

        binding.btnBack.setOnClickListener {
            findNavController().safeNavigate(R.id.testLockFragment_to_homeFragment)
        }
    }

    private fun checkLockState(){
        viewLifecycleOwner.lifecycleScope.launch {
            IntRange(1, Int.MAX_VALUE).asFlow().onEach { delay(2000) }.collect{
                ModBusController.modBusManager?.sendTo(0, MBFrame(lockIndex = -1), false, MODBUS_MIN_SEND_INTERVAL) { resData ->
                    Log.d("TestLockFragment", "检查结果---${resData.toHexString(true)}")
                    getLockDetailInfo(resData)
                }
            }
        }
    }

    private fun openLocksInOrder(){
        setBtnLockTestBg(false)
        viewLifecycleOwner.lifecycleScope.launch {
            IntRange(1, lockCount).asFlow().onEach { if (it != 1) delay(2000) }.collect{
                openLock(lockDataList[it - 1])
                setBtnLockTestBg(it == lockCount)
            }
        }

    }

    private fun setBtnLockTestBg(isEnable: Boolean){
        binding.btnLockTest.isEnabled = isEnable
        val resId = if (isEnable) R.drawable.shape_co_25_so3c9b00 else R.drawable.shape_co_25_so_fff
        binding.btnLockTest.setBackgroundResource(resId)
    }

    /**
     * 开锁，index从1开始
     */
    private fun openLock(lockStateBean: LockStateBean){
        ModBusController.modBusManager?.sendTo(0, MBFrame(lockStateBean.index - 1), false, MODBUS_MIN_SEND_INTERVAL) { resData ->
            Log.d("TestLockFragment", "开锁结果---${resData.toHexString(true)}")
        }
    }

    @SuppressLint("NotifyDataSetChanged")
    private fun getLockDetailInfo(byteArray: ByteArray){
        if (byteArray.size < 11) return
        val dataByteArray = byteArray.copyOfRange(5, byteArray.size - 1)
        Log.i("TestLockFragment",dataByteArray.toHexString())
        for ((index,item) in dataByteArray.withIndex()){
            for (bitItem in 0..7){
                val realIndex = 8 * index + bitItem
                if (realIndex > lockCount - 1) break
                lockDataList[realIndex].state = if(getBitValueFrom8Bits(item,bitItem) == 0){
                    LockStateEnum.OPEN
                } else {
                    LockStateEnum.LOCK
                }
            }
        }
        Log.i("TestLockFragment",lockDataList.toString())
        viewLifecycleOwner.lifecycleScope.launch(Dispatchers.Main) {
            dismissLoading()
            lockStateAdapter.notifyDataSetChanged()
        }
    }
}